package org.mclll.xwangplugin.town.command;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mclll.xwangplugin.MclllCustom;
import org.mclll.xwangplugin.town.config.TownContext;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static org.mclll.xwangplugin.town.command.executor.CreateTownExecutor.createNewTown;
import static org.mclll.xwangplugin.town.command.executor.CreateTownExecutor.createNewTownTabComplete;
import static org.mclll.xwangplugin.town.command.executor.DeployPlayerExecutor.deployPlayer;
import static org.mclll.xwangplugin.town.command.executor.DeployPlayerExecutor.deployPlayerTabComplete;
import static org.mclll.xwangplugin.town.command.executor.DestroyTownExecutor.destroy;
import static org.mclll.xwangplugin.town.command.executor.DestroyTownExecutor.townNameComplete;
import static org.mclll.xwangplugin.town.command.executor.InviteAcceptExecutor.accept;
import static org.mclll.xwangplugin.town.command.executor.InvitePlayerExecutor.invitePlayer;
import static org.mclll.xwangplugin.town.command.executor.InviteRejectExecutor.reject;
import static org.mclll.xwangplugin.town.command.executor.KickPlayerExecutor.kickPlayer;
import static org.mclll.xwangplugin.town.command.executor.OwnerReplaceExecutor.owner;
import static org.mclll.xwangplugin.town.command.executor.OwnerReplaceExecutor.ownerTabComplete;
import static org.mclll.xwangplugin.town.command.executor.PlayApplyJoinExecutor.applyJoin;
import static org.mclll.xwangplugin.town.command.executor.PlayApplyJoinExecutor.applyJoinTabComplete;
import static org.mclll.xwangplugin.town.command.executor.TownInfoExecutor.townInfo;
import static org.mclll.xwangplugin.town.command.executor.TownLeaveExecutor.leave;
import static org.mclll.xwangplugin.town.command.executor.TownListExecutor.townList;
import static org.mclll.xwangplugin.town.command.executor.TownNoneLeaderExecutor.noneLeader;
import static org.mclll.xwangplugin.town.command.executor.TownSetDesc.setDesc;
import static org.mclll.xwangplugin.town.command.executor.TownSetWarpExecutor.setTp;
import static org.mclll.xwangplugin.town.command.executor.TownShopAddExecutor.townShopAdd;
import static org.mclll.xwangplugin.town.command.executor.TownShopAddExecutor.townShopAddTabComplete;
import static org.mclll.xwangplugin.town.command.executor.TownShopExecutor.townShop;
import static org.mclll.xwangplugin.town.command.executor.TownShopExecutor.townShopTabComplete;
import static org.mclll.xwangplugin.town.command.executor.TownSignExecutor.sign;
import static org.mclll.xwangplugin.town.command.executor.TownSubmitTax.submitTax;
import static org.mclll.xwangplugin.town.command.executor.TownWarpExecutor.tp;
import static org.mclll.xwangplugin.town.config.TownContext.*;

/**
 * @author: geduo
 * @date: 2023/9/22 17:29
 */
public class TownCommand implements TabExecutor {

    private MclllCustom mclllCustom;

    public TownCommand(MclllCustom mclllCustom) {
        this.mclllCustom = mclllCustom;
    }

    private final List<String> PLAYER_COMMAND = Arrays.asList(
            /**
             * 邀请玩家加入城镇
             */
            "invite",
            /**
             * 同意加入城镇，镇长也可以用这个命令同意玩家加入城镇accept <申请id>
             */
            "accept",
            /**
             * 拒绝加入城镇，镇长也可以用这个命令拒绝玩家加入城镇reject <申请id>
             */
            "reject",
            /**
             * 列出城镇列表
             */
            "townList",
            /**
             * 申请加入城镇， 申请者使用applyJoin <城镇名>
             */
            "applyJoin",
            /**
             * 上交城镇税，submitTax <整数：心只石数量>
             */
            "submitTax",
            /**
             * 玩家离开诚征, leave [confirm]
             */
            "leave"
    );

    private final List<String> OP_COMMAND = Arrays.asList(
            /**
             * op派玩家加入城镇 - op使用deploy <玩家名> <城镇名> [confirm]
             */
            "deploy",
            /**
             * 创建新城镇 - op使用
             */
            "createNewTown",
            /**
             * 移除玩家的所属城镇 - op使用 kick <玩家名> [confirm]
             */
            "kick",
            /**
             * 城邦易主 - owner <玩家名> <城镇名> [confirm]
             */
            "owner",
            /**
             * 移除城镇 - destroy <城镇名> [confirm]
             */
            "destroy",
            /**
             * 设置城镇没有leader - noneLeader <城镇名> [confirm]
             */
            "noneLeader",
            /**
             * 城镇传送 - warp [playerName]
             */
            "warp",
            /**
             * 设置城镇传送点 - setWarp <城镇名> <传送标题名称>
             */
            "setWarp",
            /**
             * 城镇签到 - poi <玩家名>
             */
            "poi",
            /**
             * 城镇商店 - shop <城镇名> <玩家名>
             */
            "shop",
            /**
             * 城镇商店 - shopAdd <城镇名> <number:物品金币单价> <number:花费金币一次性最多购买物品数量> <number:一心之石购买数量>
             */
            "shopAdd",
            /**
             * 设置城镇描述 - setDesc <城镇名> <文本>
             */
            "setDesc",
            /**
             * 重载配置
             */
            "reload"
    );

    @Override
    public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
        List<String> base = Lists.newArrayList();
        base.addAll(PLAYER_COMMAND);
        if (sender.isOp()) {
            base.addAll(OP_COMMAND);
        }
        if (args.length > 1) {
            switch (args[0]) {
                case "createNewTown":
                    return createNewTownTabComplete(sender, args);
                case "accept":
                    return Collections.singletonList("list");
                case "applyJoin":
                    return applyJoinTabComplete(args);
                case "owner":
                    return ownerTabComplete(sender, args);
                case "destroy":
                case "setWarp":
                case "setDesc":
                case "noneLeader":
                    return townNameComplete(sender, args);
                case "deploy":
                    return deployPlayerTabComplete(sender, args);
                case "shop":
                    return townShopTabComplete(sender, args);
                case "shopAdd":
                    return townShopAddTabComplete(sender, args);
                default:
                    break;
            }
        } else {
            return base.stream().filter(s -> s.startsWith(args[0])).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
        if (args.length > 0 && StringUtils.isNotBlank(args[0])) {
            // 非OP指令
            switch (args[0]) {
                case "townList":
                    townList(sender, args);
                    return true;
                case "townInfo":
                    townInfo(sender, args);
                    return true;
                case "invite":
                    if (sender instanceof Player) {
                        invitePlayer((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                case "submitTax":
                    if (sender instanceof Player) {
                        submitTax((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                case "accept":
                    if (sender instanceof Player) {
                        accept((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                case "reject":
                    if (sender instanceof Player) {
                        reject((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                case "applyJoin":
                    if (sender instanceof Player) {
                        applyJoin((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                case "leave":
                    if (sender instanceof Player) {
                        leave((Player) sender, args);
                        return true;
                    }
                    sender.sendMessage(ONLY_PLAYER_COMMAND);
                    break;
                default:
                    if (!sender.isOp()) {
                        sender.sendMessage(UNKNOWN_COMMAND);
                    }
                    break;
            }
            //OP指令
            if (sender.isOp()) {
                switch (args[0]) {
                    case "createNewTown":
                        createNewTown(sender, args);
                        break;
                    case "kick":
                        kickPlayer(sender, args);
                        break;
                    case "deploy":
                        deployPlayer(sender, args);
                        break;
                    case "reload":
                        mclllCustom.reloadConfig();
                        TownContext.reloadConfig(mclllCustom.getDataFolder());
                        sender.sendMessage("重载配置成功");
                        break;
                    case "owner":
                        owner(sender, args);
                        break;
                    case "noneLeader":
                        noneLeader(sender, args);
                        break;
                    case "destroy":
                        destroy(sender, args);
                        break;
                    case "poi":
                        sign(sender, args);
                        break;
                    case "warp":
                        tp(sender, args);
                        break;
                    case "setWarp":
                        if (sender instanceof Player) {
                            setTp((Player) sender, args);
                            break;
                        }
                        sender.sendMessage(ONLY_PLAYER_COMMAND);
                        break;
                    case "shop":
                        townShop(sender, args);
                        break;
                    case "shopAdd":
                        if (sender instanceof Player) {
                            townShopAdd((Player)sender, args);
                            break;
                        }
                        sender.sendMessage(ONLY_PLAYER_COMMAND);
                        break;
                    case "setDesc":
                        setDesc(sender, args);
                        break;
                    default:
                        sender.sendMessage(UNKNOWN_COMMAND);
                        return false;
                }
                return true;
            }
        } else {
            String message = COMMAND_HELP;
            if (sender.isOp()) {
                message += OP_ONLY_COMMAND_HELP;
            }
            sender.sendMessage(message);
            return true;
        }
        return false;
    }
}
